package lock8;

import java.util.concurrent.TimeUnit;

/**
 *Description:
 * 8锁测试
 * 同一个锁才会阻塞等待，不同对象之间，对象和模板之间的锁是不会阻塞影响的。
 *
 *Version:1.0.0
 *@author shihb
 *@date 2020/9/8 20:13
 */
public class Lock8Q {

  public static void main(String[] args) {



//    test1();
//    test2();
//      test3();
      test4();
  }


  private static void test1() {
    // 1、先发短信还是打电话？
    // 2、发短信延迟四秒后呢？
    // 答案都是发短信，因为synchronized锁的对象是方法的调用者
    // 3、新增线程C执行普通方法会是什么样的执行顺序。
    // 答案：hello 发短信 打电话。普通方法没有锁不受锁的方法。
    phone phone = new phone();
    new Thread(()->{
      phone.smsg();
    },"A").start();
    new Thread(()->{
      phone.call();
    },"A").start();
    new Thread(()->{
      phone.hello();
    },"C").start();
  }

  private static void test2() {
    // 4、两个对象，请问是先打印发短信还是打电话；打电话
    phone phone1 = new phone();
    phone phone2 = new phone();
    new Thread(()->{
      phone1.smsg();
    },"A").start();
    new Thread(()->{
      phone2.call();
    },"A").start();

  }

  private static void test3() {
    //5、两个都是静态方法，请问是先打印发短信还是打电话
    //6、两个对象，请问是先打印发短信还是打电话
    // 答案都是发短信，锁的是模板，全局唯一
    phone2 phone1 = new phone2();
    phone2 phone2 = new phone2();
    new Thread(()->{
      phone1.smsg();
    },"A").start();
    new Thread(()->{
      phone2.call();
    },"A").start();

  }
  private static void test4() {
    //5、一个静态方法，一个普通，请问是先打印发短信还是打电话
    //6、两个对象，请问是先打印发短信还是打电话
    // 答案是打电话，因为静态锁的模板类，普通锁的是对象,锁不是同一个
    phone3 phone1 = new phone3();
//    phone2 phone2 = new phone2();
    new Thread(()->{
      phone1.smsg();
    },"A").start();
    new Thread(()->{
      phone1.call();
    },"A").start();
  }
}
class phone3{
  public static synchronized void smsg()  {

    try {
      TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    System.out.println("发短信");
  }
  public synchronized void call(){

    System.out.println("打电话");
  }
}




class phone2{
  public static synchronized void smsg()  {

    try {
      TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    System.out.println("发短信");
  }
  public  static synchronized void call(){

    System.out.println("打电话");
  }
  public void hello(){
    System.out.println("hello");
  }
}


class phone{
  public synchronized void smsg()  {

    try {
      TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    System.out.println("发短信");
  }
  public synchronized void call(){

    System.out.println("打电话");
  }
  public void hello(){
    System.out.println("hello");
  }
}
